package jwt

import (
	"gitee.com/lstack_light/light-utils/common"
	"gitee.com/lstack_light/light-utils/common/errorCode"
	"gitee.com/lstack_light/light-utils/common/response"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

// Key 自定义一个字符串
var key = []byte("light")

type Claims struct {
	UserId string
	jwt.StandardClaims
}

type TokenResult struct {
	Token      string
	ExpireTime int64
}

// CreateToken
/**
 * @description 颁发token
 * @author KangXu
 * @param userId 用户id
 * @return TokenResult, error
 */
func CreateToken(userId string) (TokenResult, error) {
	expireTime := time.Now().Add(3 * 24 * time.Hour)
	claims := &Claims{
		UserId: userId,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(), //过期时间
			IssuedAt:  time.Now().Unix(),
			Issuer:    "127.0.0.1",     // 签名颁发者
			Subject:   "light subject", //签名主题
		},
	}
	newWithClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := newWithClaims.SignedString(key)
	if err != nil {
		return TokenResult{}, err
	}
	return TokenResult{Token: token, ExpireTime: expireTime.Unix()}, nil
}

// ParseToken
/**
 * description 解析token
 * @author KangXu
 * @param token 需要解析的token
 * @return *Claims, error
 */
func ParseToken(token string) (*Claims, error) {
	claims := &Claims{}
	_, err := jwt.ParseWithClaims(token, claims, func(jwtToken *jwt.Token) (i interface{}, err error) {
		return key, nil
	})
	return claims, err
}

// CheckToken 校验token的中间件
func CheckToken() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		token := ctx.GetHeader(common.HeaderAuthorization)
		if "" == token {
			ctx.JSON(http.StatusUnauthorized, response.CustomizeError(errorCode.PermissionError))
			ctx.Abort()
			return
		}
		claims, err := ParseToken(token)
		if nil != err {
			ctx.JSON(http.StatusUnauthorized, response.CustomizeError(errorCode.PermissionError, "检测到存在恶意访问"))
			ctx.Abort()
			return
		}
		ctx.Request.Header.Add(common.HeaderUser, claims.UserId)
	}
}
